/**
 * 
 */
package com.wilmar.process.core.services.api;

import java.util.Map;
import java.util.Set;

import org.jbpm.api.ProcessInstance;
import org.jbpm.api.model.ActivityCoordinates;

import com.wilmar.process.entity.InstanceOperateOpinion;
import com.wilmar.process.entity.ProcessInstanceHelper;
import com.wilmar.process.entity.User;
import com.wilmar.process.entity.vo.ProcessInstanceVO;
import com.wilmar.process.exception.DirtyDataException;
import com.wilmar.process.exception.ObjectNotFoundException;
import com.wilmar.process.exception.PermissionDeniedException;

/**
 * 工作流子系统中关于工作流实例的核心服务接口
 * 
 * @author MaKuBEX E-mail:makubexnet@gmail.com
 * @version 2.0.1 at Jul 31, 2009 9:05:59 AM
 * 
 */
public interface ISystemProcessInstanceService extends
		IBaseService<ProcessInstanceVO, ProcessInstance> {

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionId
	 *            流程定义编号
	 * @param user
	 *            启动用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceById(String processDefinitionId, User user)
			throws PermissionDeniedException, DirtyDataException;

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionId
	 *            流程定义编号
	 * @param variableMap
	 *            启动附属参数
	 * @param user
	 *            启用用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceByIdWithVariable(
			String processDefinitionId, Map<String, ?> variableMap, User user)
			throws PermissionDeniedException, DirtyDataException;

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionKey
	 *            流程实例关键字
	 * @param user
	 *            启动用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceByKey(String processDefinitionKey,
			User user) throws PermissionDeniedException, DirtyDataException;

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionKey
	 *            流程实例关键字
	 * @param variableMap
	 *            启动附属参数
	 * @param user
	 *            启动用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceByKeyWithVariable(
			String processDefinitionKey, Map<String, ?> variableMap, User user)
			throws PermissionDeniedException, DirtyDataException;

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionId
	 *            流程定义编号
	 * @param processInstanceKey
	 *            流程实例关键字
	 * @param user
	 *            启动用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceById(String processDefinitionId,
			String processInstanceKey, User user)
			throws PermissionDeniedException, DirtyDataException;

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionId
	 *            流程定义编号
	 * @param processInstanceKey
	 *            流程实例关键字
	 * @param map
	 *            启动附属参数
	 * @param user
	 *            启用用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceByIdWithVariable(
			String processDefinitionId, String processInstanceKey,
			Map<String, ?> map, User user) throws PermissionDeniedException,
			DirtyDataException;

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionKey
	 *            流程定义关键字
	 * @param processInstanceKey
	 *            流程实例关键字
	 * @param user
	 *            启动用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceByKey(String processDefinitionKey,
			String processInstanceKey, User user)
			throws PermissionDeniedException, DirtyDataException;

	/**
	 * 启动一个流程实例
	 * 
	 * @param processDefinitionKey
	 *            流程定义关键字
	 * @param processInstanceKey
	 *            流程实例关键字
	 * @param variableMap
	 *            启动附属参数
	 * @param user
	 *            启动用户
	 * @return 流程实例编号
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 * @throws DirtyDataException
	 *             验证时发现有脏数据
	 */
	public String startProcessInstanceByKeyWithVariable(
			String processDefinitionKey, String processInstanceKey,
			Map<String, ?> variableMap, User user)
			throws PermissionDeniedException, DirtyDataException;

	/**
	 * 根据提供的流程实例编号获取对应的流程帮助对象
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @return 流程帮助对象
	 * @throws ObjectNotFoundException
	 *             如果流程实例中没有流程帮助对象
	 */
	public ProcessInstanceHelper getProcessInstanceHelperById(
			String processInstanceId) throws ObjectNotFoundException;

	/**
	 * 根据提供的流程实例编号以及变量的名称获取流程实例中对应变量的值
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @param variableName
	 *            变量名称
	 * @return 流程变量对应的值
	 * @throws ObjectNotFoundException
	 *             如果流程实例中没有对应的变量
	 */
	public Object getVariable(String processInstanceId, String variableName)
			throws ObjectNotFoundException;

	/**
	 * 终止一个流程实例
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @param user
	 *            用户
	 * @param outerSystem
	 *            用户所在外部系统名称
	 * @throws PermissionDeniedException
	 *             当用户没有被授权发起该流程时
	 */
	public void stopProcessInstanceById(String processInstanceId, User user)
			throws PermissionDeniedException;

	/**
	 * 暂停一个正在执行的流程实例
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @param user
	 *            流程终止人
	 * @throws PermissionDeniedException
	 *             当前用户没有被授权暂停该流程实例
	 * @throws ObjectNotFoundException
	 *             如果当前流程实例已经结束
	 */
	public void suspendProcessInstanceById(String processInstanceId, User user)
			throws PermissionDeniedException, ObjectNotFoundException;

	/**
	 * 根据流程实例编号获取当前实例活动节点的座标
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @return 流程实例活动节点座标
	 * @throws ObjectNotFoundException
	 *             当流程实例已经结束
	 */
	public Set<ActivityCoordinates> getActivityCoordinates(
			String processInstanceId) throws ObjectNotFoundException;

	/**
	 * 根据流程实例编号找到对应的流程实例实体
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @return 流程实例实体
	 * @throws ObjectNotFoundException
	 *             当流程实例编号没有对应的流程实体时
	 */
	public ProcessInstance getDetailById(String processInstanceId)
			throws ObjectNotFoundException;

	/**
	 * 根据流程实例关键字以及流程定义关键字在指定的流程定义中找到对应的流程实例实体
	 * 
	 * @param processDefinitionKey
	 *            流程定义关键字
	 * @param processInstanceKey
	 *            流程实例关键字
	 * @return 流程实例实体
	 * @throws ObjectNotFoundException
	 *             当流程实例编号没有对应的流程实体时
	 */
	public Set<ProcessInstance> getDetailByKey(String processDefinitionKey,
			String processInstanceKey) throws ObjectNotFoundException;

	/**
	 * 根据流程实例关键字找到对应的流程实例实体
	 * 
	 * @param processInstanceKey
	 *            流程实例关键字
	 * @return 流程实例实体
	 * @throws ObjectNotFoundException
	 *             当流程实例编号没有对应的流程实体时
	 */
	public Set<ProcessInstance> getDetailByKey(String processInstanceKey)
			throws ObjectNotFoundException;

	/**
	 * 创建或者更新流程实例中的变量值
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @param name
	 *            变量名称
	 * @param value
	 *            变量值
	 */
	public void createOrUpdateVariable(String processInstanceId, String name,
			Object value);

	/**
	 * 创建或者更新流程实例中的变量值
	 * 
	 * @param processInstanceId
	 *            任务实例编号
	 * @param variableMap
	 *            变量
	 */
	public void createOrUpdateVariables(String processInstanceId,
			Map<String, ?> variableMap);

	/**
	 * 获取当前流程实例编号对应的流程定义描述
	 * 
	 * @param processInstanceId
	 *            流程实例编号
	 * @return 流程定义描述
	 * @throws ObjectNotFoundException
	 *             如果对应的流程实例没有被找到,或者该流程实例已经结束
	 */
	public String getProcessDescription(String processInstanceId)
			throws ObjectNotFoundException;

	/**
	 * 根据流程实例编号编号流转流程
	 * 
	 * @param ProcessInstanceId
	 *            流程实例编号
	 * @param user
	 *            用户
	 * @param opinion
	 *            处理意见
	 * @return 流程实例实体
	 */
	public ProcessInstance signalProcessInstanceById(String ProcessInstanceId,
			User user, InstanceOperateOpinion opinion);

	/**
	 * 根据流程实例编号编号流转流程
	 * 
	 * @param ProcessInstanceId
	 *            流程实例编号
	 * @param variables
	 *            需要增加或者替换的流程变量
	 * @param user
	 *            用户
	 * @param opinion
	 *            处理意见
	 * @return 流程实例实体
	 */
	public ProcessInstance signalProcessInstanceById(String ProcessInstanceId,
			Map<String, ?> variables, User user, InstanceOperateOpinion opinion);

	/**
	 * 根据流程实例编号编号流转流程
	 * 
	 * @param ProcessInstanceId
	 *            流程实例编号
	 * @param signalName
	 *            流转流向
	 * @param user
	 *            用户
	 * @param opinion
	 *            处理意见
	 * @return 流程实例实体
	 */
	public ProcessInstance signalProcessInstanceById(String ProcessInstanceId,
			String signalName, User user, InstanceOperateOpinion opinion);

	/**
	 * 根据流程实例编号编号流转流程
	 * 
	 * @param ProcessInstanceId
	 *            流程实例编号
	 * @param variables
	 *            需要增加或者替换的流程变量
	 * @param signalName
	 *            流转流向
	 * @param user
	 *            用户
	 * @param opinion
	 *            处理意见
	 * @return 流程实例实体
	 */
	public ProcessInstance signalProcessInstanceById(String ProcessInstanceId,
			Map<String, ?> variables, String signalName, User user,
			InstanceOperateOpinion opinion);

}
